﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;

namespace ULibArtreve.security
{
    public static class Crypto
    {
        //COMPUTE HASH
        public static string ComputeHashMD5(string input)
        {
            try
            {
                byte[] tmpSource;
                byte[] tmpHash;
                //Create a byte array from source data
                tmpSource = Encoding.Unicode.GetBytes(input);

                //Compute hash based on source data
                tmpHash = new MD5CryptoServiceProvider().ComputeHash(tmpSource);
                //RETURN
                return ByteArrayToString(tmpHash);
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message, ex);
            }
        }
        //COMPUTE HASH
        public static string ComputeHashSHA1(string input, string validationKey)
        {
            try
            {
                byte[] tmpSource;
                byte[] tmpHash;

                //CREATE HASH
                HMACSHA1 hash = new HMACSHA1();
                hash.Key = HexToByteArray(validationKey);

                //Create a byte array from source data
                tmpSource = Encoding.Unicode.GetBytes(input);

                //Compute hash based on source data
                tmpHash = hash.ComputeHash(tmpSource);

                //RETURN
                return Convert.ToBase64String(tmpHash);
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message, ex);
            }
        }
        //COMPUTE HASH
        public static string ComputeHashSHA256(string input, string validationKey)
        {
            try
            {
                byte[] tmpSource;
                byte[] tmpHash;

                //CREATE HASH
                HMACSHA256 hash = new HMACSHA256();
                hash.Key = HexToByteArray(validationKey);

                //Create a byte array from source data
                tmpSource = Encoding.Unicode.GetBytes(input);

                //Compute hash based on source data
                tmpHash = hash.ComputeHash(tmpSource);

                //RETURN
                return Convert.ToBase64String(tmpHash);
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message, ex);
            }
        }
        //CONVERT BYTEARRAY TO STRING
        public static string ByteArrayToString(byte[] arrInput)
        {
            int i;
            StringBuilder sOutput = new StringBuilder(arrInput.Length);
            for (i = 0; i < arrInput.Length - 1; i++)
            {
                sOutput.Append(arrInput[i].ToString("X2"));
            }
            return sOutput.ToString();
        }
        //CONVERT HEXADECIMAL STRING TO BYTE ARRAY
        public static byte[] HexToByteArray(string hexString)
        {
            byte[] returnBytes = new byte[hexString.Length / 2];
            for (int i = 0; i < returnBytes.Length; i++)
                returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
            return returnBytes;
        }
        //BASE64
        public static string EncodeTo64(string toEncode, Encoding encoding)
        {
            byte[] toEncodeAsBytes = null;
            if (encoding == ASCIIEncoding.ASCII)
            {
                toEncodeAsBytes = System.Text.ASCIIEncoding.ASCII.GetBytes(toEncode);
            }
            else if (encoding == UTF8Encoding.UTF8)
            {
                toEncodeAsBytes = System.Text.UTF8Encoding.UTF8.GetBytes(toEncode);
            }
            else
            {
                throw new Exception("Character encoding not supported");
            }
            return System.Convert.ToBase64String(toEncodeAsBytes);
        }
        public static string DecodeFrom64(string encodedData, Encoding encoding)
        {
            byte[] encodedDataAsBytes = System.Convert.FromBase64String(encodedData);
            if (encoding == ASCIIEncoding.ASCII)
            {
                return System.Text.ASCIIEncoding.ASCII.GetString(encodedDataAsBytes);
            }
            else if (encoding == UTF8Encoding.UTF8)
            {
                return System.Text.UTF8Encoding.UTF8.GetString(encodedDataAsBytes);
            }
            throw new Exception("Character encoding not supported");
        }
    }
}